/**
 * 40个测试点只错了1个点，但是没有发现是哪里错了
 * 已发现，统计了正下方的点，后处理也没有处理干净，当问题点与整点有重合时
 * 
 * 假设有2条直线
 * y = x + k1
 * y = -x + k2
 * 如果某个点同时在这两条直线下方，称为好的。注意位于直线上则不是好点。
 * 
 * 现在给定N个整点以及Q个询问，每一次询问给定k1和k2
 * 问有多少个好点。
 * 
 * 首先注意到两条直线相较于((k2-k1)/2, (k2+k1)/2)，且这两条直线垂直
 * 因此如果把坐标轴顺时针选择45度，则该题目等价于问位于交点右下的点的数量
 * 然后需要反复问多次，因此这是一个二维偏序的经典题目
 * 
 * 坐标系旋转的变换矩阵
 *   cos(jiao) sin(jiao)
 *  -sin(jiao) cos(jiao)
 * 对于顺时针45度而言就是: 
 *     转后的x = (x - y) * sqrt(2) / 2
 *     转后的y = (x + y) * sqrt(2) / 2 
 * 考虑到是求相对位置关系，因此后面的实数计算可以省略
 * 
 * 最后转为经典的CDQ分治
 * 1. 严格右下
 * 2. 问题点不能参与统计
 * 
 * 因此设计一个flag，统计点flag为1，问题点flag为0
 * 在CDQ中只统计flag为1的数量
 * 
 * 第一维从大到小排序，保证排在后面的点都无需统计
 * 如果第二关键字设置为第二维从小到大排序，就会发生正下方点被计数的bug
 * 当场其实发现了这个bug，并且做了后处理，但是有一个点没有处理干净，且后续修改也没有完全改对，总是wa这个点
 * 因此将第二维关键字改为按照flag升序排列，所有问题点都靠前即可
 * 第三关键字再用第二维从小到大即可
 * 
 * 不如用树状数组方便
 * 使用树状数组也需要正确排序，第二关键字要用flag，否则仍然有问题
 */

#include <bits/stdc++.h>
using namespace std;

using llt = long long;

struct Point{
    llt x, y;
    Point(llt a = 0, llt b = 0):x(a),y(b){}
    void input(){
        cin >> x >> y;
    }
};

// 顺时针45度
void rotate(Point & p){
    llt x = (p.x - p.y);
    llt y = (p.x + p.y);
    p.x = x, p.y = y;
}

int N, Q;
vector<Point> P, QP;

struct cdq_t{
    llt x;
    llt y;
    int pos;
    int flag;
    cdq_t(llt a=0, llt b=0, int c=0, int d=0):x(a),y(b),pos(c),flag(d){}
};

vector<cdq_t> A, B;
vector<int> Ans;
map<llt, vector<llt>, less<llt>> MapX;

void CDQ(int s, int e){
    if(s >= e) return;
    
    int mid = (s + e) >> 1;
    CDQ(s, mid); CDQ(mid + 1, e);

    int u = s, v = mid + 1, t = s;
    int flag = 0;
    while(u <= mid and v <= e){
        if(A[u].y < A[v].y){
            flag += A[u].flag;
            B[t++] = A[u++];
        }else{
            Ans[A[v].pos] += flag;
            B[t++] = A[v++];
        }
    }
    while(u <= mid){
        flag += A[u].flag;
        B[t++] = A[u++];
    }
    while(v <= e){
        Ans[A[v].pos] += flag;
        B[t++] = A[v++];
    }

    copy(B.begin() + s, B.begin() + e + 1, A.begin() + s);
    return;
}

void work(){
    cin >> N >> Q;
    P.assign(N, {});
    for(auto & p : P){
        p.input();
        p.x <<= 1;
        p.y <<= 1;
        rotate(p);
    }
    QP.assign(Q, {});
    for(auto & p : QP){
        llt k1, k2;
        cin >> k1 >> k2;
        p.x = (k2 - k1);
        p.y = (k1 + k2);
        rotate(p);
    }

    A.clear();
    A.reserve(N + Q);

    int k = 0;
    for(const auto & p : P){
        A.push_back({p.x, p.y, k++, 1});
    }
    for(const auto & p : QP){
        A.push_back({p.x, p.y, k++, 0});
    }

    assert(A.size() == N + Q);
    B.assign(N + Q, {});
    Ans.assign(N + Q, 0);
    sort(A.begin(), A.end(), [](const cdq_t & a, const cdq_t & b)->bool{
        if(a.x != b.x) return a.x > b.x;
        if(a.flag != b.flag) return a.flag < b.flag;
        if(a.y != b.y) return a.y < b.y;
        return a.pos < b.pos;
    });
    CDQ(0, Ans.size() - 1);

    // for(const auto & p : P){
    //     MapX[p.x].emplace_back(p.y);
    // }

    // for(auto & p : MapX){
    //     sort(p.second.begin(), p.second.end(), less<llt>());
    // }

    for(int i=N;i<N+Q;++i){
        cout << Ans[i] << "\n";
    }
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    int nofkase = 1;
    while(nofkase--) work();
	return 0;
}